/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package mware_lib;

import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import mware_lib.Communicator.Connection;
import mware_lib.Communicator.Server;

/**
 * dieser thread wird für jeden objektbroker gestartet. er nimmt alle einkommenden
 * "nachrichten" des request reply protokolls entgegen
 * @author safe
 */
public class ListenerThread extends Thread {

    private Server server;
    private ObjectBroker broker;
    private List<RequestThread> requestThreads;

    public ListenerThread(Server server, ObjectBroker broker) {
        this.server = server;
        this.broker = broker;
        this.requestThreads = new LinkedList();
        System.out.println("ListenerThread gestartet");
    }

    private synchronized void cleanThreadPool() {
        // wenn das interrupt flag true ist werden die in der liste gespeicherten
        // requestthreads noch sauber beendet

        for (RequestThread thread : requestThreads) {
            try {
                thread.interrupt();
                thread.shutDownSocket();
                // warten auf beenden des requestthreads
                thread.join();

            } catch (IOException ex) {
                System.out.println("Thread beendet " + ex.getMessage());
            } catch (InterruptedException ex) {
                System.out.println(ex.getMessage());
            }
        }
    }

    /** 
     * alle threads, die anfragen bearbeiten sollen(requestthreads)
     * werden hier in einer liste verwaltet, wenn sie noch leben
     */
    private synchronized void removeInactiveThreads() {
        RequestThread threadElem;
        for(int i = 0; i < requestThreads.size(); i++){
            threadElem = requestThreads.get(i);
            if (!threadElem.isAlive()) {
                requestThreads.remove(threadElem);
            }
        }
    }

    private synchronized void addTorequestThreads(RequestThread thread) {
        this.requestThreads.add(thread);
    }

    /**
     * um diesen listener sauber zu beenden
     * @throws IOException 
     */
    protected void shutDownSocket() throws IOException {
        server.shutdown();
    }

    /**
     * wartet auf eingehende verbindungen und erstellt einen neuen "arbeiter" wenn 
     * informationen ankommen und verarbeitet werden sollen
     */
    @Override
    public void run() {
        Connection connection;

        while (!isInterrupted()) {
            try {
                connection = server.getConnection();
                RequestThread thread = new RequestThread(connection, broker);
                thread.start();

                this.addTorequestThreads(thread);
                this.removeInactiveThreads();

            } catch (IOException ex) {
                if (!ex.getMessage().equals("socket closed")) {
                    System.out.println("ListenerThread : getConnection Fehler. Message: " + ex.getMessage());
                }
                Thread.currentThread().interrupt();
            }
        }
        cleanThreadPool();

    }
}
